package com.zmxstudy.gzu.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.indices.AnalyzeRequest;
import co.elastic.clients.elasticsearch.indices.AnalyzeResponse;
import co.elastic.clients.elasticsearch.indices.analyze.AnalyzeToken;
import co.elastic.clients.elasticsearch.sql.QueryRequest;
import co.elastic.clients.elasticsearch.sql.QueryResponse;
import co.elastic.clients.json.JsonData;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.zmxstudy.gzu.domain.TbBrand;
import com.zmxstudy.gzu.domain.TbCategory;
import com.zmxstudy.gzu.domain.TbSku;
import com.zmxstudy.gzu.domain.TbSpu;
import com.zmxstudy.gzu.domain.es.Query;
import com.zmxstudy.gzu.domain.es.SkuInfo;
import com.zmxstudy.gzu.mapper.TbBrandMapper;
import com.zmxstudy.gzu.mapper.TbCategoryMapper;
import com.zmxstudy.gzu.mapper.TbSkuMapper;
import com.zmxstudy.gzu.mapper.TbSpuMapper;
import com.zmxstudy.gzu.service.SkuEsMapper;
import com.zmxstudy.gzu.service.SkuService;
import jakarta.annotation.Resource;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.List;

@Data
@Document(indexName = "all-files")
@JsonIgnoreProperties(ignoreUnknown = true)
@Service
public class SkuServiceImpl implements SkuService {
    @Resource
    private TbSkuMapper tbSkuMapper;
    @Resource
    private SkuEsMapper skuEsMapper;
    @Resource
    private TbSpuMapper tbSpuMapper;
    @Resource
    private TbBrandMapper tbBrandMapper;
    @Resource
    private TbCategoryMapper tbCategoryMapper;
    @Resource
    private ElasticsearchTemplate esTemplate;
    @Resource
    private ElasticsearchClient elasticsearchClient;

    /**
     * 导入sku数据到es
     */
    @Override
    public void importSku() {
        LambdaQueryWrapper<TbSku> lqw = new LambdaQueryWrapper<TbSku>();
        lqw.eq(TbSku::getStatus, '1');
        List<TbSku> skuListResult = tbSkuMapper.selectList(lqw);
        //将数据转成search.Sku
        List<SkuInfo> skuInfos = JSON.parseArray(JSON.toJSONString(skuListResult), SkuInfo.class);
        for (SkuInfo item:skuInfos) {
            String str = "";
            str = str + item.getName() + item.getWeight() + item.getSpec();
            TbSpu tbSpu = tbSpuMapper.selectById(item.getSpuId());
            if (tbSpu != null){
                str = str + tbSpu.getName() + tbSpu.getCaption() + tbSpu.getIntroduction();
            }
//            TbBrand tbBrand = tbBrandMapper.selectById(item.getBrandId());
//            if (tbBrand != null){
//                str = str + tbBrand.getName();
//            }
//            TbCategory tbCategory = tbCategoryMapper.selectById(item.getCategoryId());
//            if (tbCategory != null){
//                str = str + tbCategory.getCategoryName() + tbCategory.getIntroduction();
//            }
            item.setAll(str);
        }
        skuEsMapper.saveAll(skuInfos);
        System.out.println("***************************************************");
    }


    @Override
    public SearchResponse<SkuInfo> search(Query query) {
        if (query.getInput() == null){
            query.setInput("");
        }
        if (query.getBrand() == null){
            query.setBrand("");
        }
        if (query.getSpec() == null){
            query.setSpec("");
        }
        String str = ""+query.getInput()+query.getBrand()+query.getSpec();

        SearchResponse<SkuInfo> searchResponse = null;
        if (str.equals("")){

            SearchRequest searchRequest = new SearchRequest.Builder().size(10000).build();
            try {
                searchResponse = elasticsearchClient.search(searchRequest, SkuInfo.class);
                System.out.println(searchResponse);
                return searchResponse;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }




        // 执行查询
        if (query.getSort() == null){
            try {
                searchResponse = elasticsearchClient.search(srBuilder -> srBuilder
                                .index("skuinfo")
                                .size(10000)
                                .query(r->r
                                        .bool(v->v
                                                .must(o->o
                                                        .match(c->c
                                                                .field("All")
                                                                .query(str)
                                                                .operator(Operator.And)
                                                        )
                                                )
                                                .must(ss->ss
                                                        .range(rr->rr
                                                                .field("price")
                                                                .gte(JsonData.of(query.getGt()))
                                                                .lt(JsonData.of(query.getLt()))
                                                        )
                                                )
                                        )
                                )
                        , SkuInfo.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else {
            if (query.getJudge() == 1){
                try {
                    searchResponse = elasticsearchClient.search(srBuilder -> srBuilder
                                    .index("skuinfo")
                                    .size(10000)
                                    .query(r->r
                                            .bool(v->v
                                                    .must(o->o
                                                            .match(c->c
                                                                    .field("All")
                                                                    .query(str)
                                                                    .operator(Operator.And)
                                                            )
                                                    )
                                                    .must(ss->ss
                                                            .range(rr->rr
                                                                    .field("price")
                                                                    .gte(JsonData.of(query.getGt()))
                                                                    .lt(JsonData.of(query.getLt()))
                                                            )
                                                    )
                                            )
                                    )
                                    .sort(sortOptionsBuilder -> sortOptionsBuilder
                                            .field(fieldSortBuilder -> fieldSortBuilder
                                                    .field(query.getSort()).order(SortOrder.Desc)
                                            )
                                    )
                            , SkuInfo.class);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            else {
                try {
                    searchResponse = elasticsearchClient.search(srBuilder -> srBuilder
                                    .index("skuinfo")
                                    .size(10000)
                                    .query(r->r
                                            .bool(v->v
                                                    .must(o->o
                                                            .match(c->c
                                                                    .field("All")
                                                                    .query(str)
                                                                    .operator(Operator.And)
                                                            )
                                                    )
                                                    .must(ss->ss
                                                            .range(rr->rr
                                                                    .field("price")
                                                                    .gte(JsonData.of(query.getGt()))
                                                                    .lt(JsonData.of(query.getLt()))
                                                            )
                                                    )
                                            )
                                    )
                                    .sort(sortOptionsBuilder -> sortOptionsBuilder
                                            .field(fieldSortBuilder -> fieldSortBuilder
                                                    .field(query.getSort()).order(SortOrder.Asc)
                                            )
                                    )
                            , SkuInfo.class);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //解析查询结果
        for (Object i:searchResponse.hits().hits()) {
            System.out.println(i);
        }
        System.out.println(searchResponse.hits().hits());
        return searchResponse;

    }


    @Override
    public SearchResponse<SkuInfo> sort(){
        SearchResponse<SkuInfo> searchResponse = null;
        try {
            searchResponse = elasticsearchClient.search(srBuilder -> srBuilder
                            .index("skuinfo")
                            // MultiMatch 查找：对输入内容先分词再查询。
                            .query(queryBuilder -> queryBuilder
                                    .range(rangeQueryBuilder -> rangeQueryBuilder
                                            .field("price")
                                            .gte(JsonData.of(0))
                                            .lt(JsonData.of(3000)))
                            )
                            .sort(sortOptionsBuilder -> sortOptionsBuilder
                                    .field(fieldSortBuilder -> fieldSortBuilder
                                            .field("price").order(SortOrder.Asc)
                                    )
                            )

                    , SkuInfo.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //解析查询结果
        return searchResponse;

    }

    @Override
    public SearchResponse<SkuInfo> abc() {
        String name= "手机";
        AnalyzeRequest analyzeRequest = new AnalyzeRequest.Builder().text(name).build();
        try {
            AnalyzeResponse response = elasticsearchClient.indices().analyze(analyzeRequest);
            List<AnalyzeToken> tokens = response.tokens();
            for (AnalyzeToken i:tokens){
                System.out.println(i);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String query= """
                select * from skuinfo where match('All','"""+name+
                """
                ') and price >3000 and price <4000 order by 'price' desc
                """;
        QueryRequest queryRequest=new QueryRequest.Builder().query(query).build();
        try {
            QueryResponse queryResponse = elasticsearchClient.sql().query(queryRequest);
            List<List<JsonData>> rows = queryResponse.rows();
            for (List<JsonData> row1:rows){
                System.out.println(row1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


}
